package com.aboverock.module.shiro.realms;

import com.aboverock.common.enums.UserStatusEnum;
import com.aboverock.core.token.LdapUserLoginToken;
import com.aboverock.module.system.domain.User;
import com.aboverock.module.system.service.LdapService;
import com.aboverock.module.system.service.UserRoleService;
import com.aboverock.module.system.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.ldap.DefaultLdapRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

/**
 * LDAP账号密码匹配.
 * 
 * @author Rock Wang
 *
 */
public class LdapShiroRealm extends DefaultLdapRealm {

    private Logger logger = LoggerFactory.getLogger(LdapShiroRealm.class);

    @Autowired
    private LdapService ldapService;

    @Autowired
    @Lazy
    private UserService userService;

    // @Autowired
    // @Lazy
    // private DatalakeService datalakeService;

    @Autowired
    @Lazy
    private UserRoleService userRoleService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof LdapUserLoginToken;
    }

    public LdapShiroRealm() {
        setAuthorizationCachingEnabled(false);
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String loginName = token.getPrincipal().toString();
        User user = userService.getADUserByLoginName(loginName);
        if (user != null && user.getStatus().equals(UserStatusEnum.LOCKED.getValue())) {
            throw new LockedAccountException(loginName + "'s account is locked");
        }

        logger.debug("Data-Smart: LDAP认证登录用户{}", loginName);
        SimpleAuthenticationInfo authenticationInfo = null;
        String credentials = new String((char[]) token.getCredentials());
        if (ldapService.authenticate(loginName, credentials)) {
            authenticationInfo = new SimpleAuthenticationInfo(loginName, credentials, getName());
        }

        // 认证成功后，如果本地数据库中没有当前登录用户信息则录入
        if (null == user) {
            // try {
            //     long start = System.currentTimeMillis();
            //     user = datalakeService.getUserByLoginName(loginName);
            //     logger.info("Data-Smart: 数据湖同步用户耗时{}", System.currentTimeMillis() - start);
            // } catch (DatalakeRequestException | DatalakeDataParseException e) {
            //     logger.warn("Data-Smart: 从数据湖获取用户{}信息失败", loginName, e);
            // }
            //
            // // 从数据湖获取用户信息失败
            // if (null == user) {
            //     user = new User();
            // }
            //
            // user.setLoginName(loginName);
            // if (StringUtils.isBlank(user.getName())) {
            //     user.setName(loginName);
            // }
            // user.setPassword(ShiroHashEncryptUtil.encrypt(credentials));
            // // 设置创建与更新用户
            // user.setCreateUser(loginName);
            // user.setUpdateUser(loginName);
            // User newUser = userService.saveDataLakeEmpInfoToDb(user);
            // if (null != newUser) {
            //     if (!userRoleService.addCommonRole(newUser.getId())) {
            //         logger.warn("Data-Smart: 给用户{}添加通用角色失败", newUser.getLoginName());
            //     }
            // }
        }

        return authenticationInfo;
    }

}
